package com.anycl.customer.service.impl;

import com.anycl.customer.constant.Constants;
import com.anycl.customer.dao.CustomerRepository;
import com.anycl.customer.dao.impl.CustomerRepositoryImpl;
import com.anycl.customer.entity.Customer;
import com.anycl.customer.exception.CustomerException;
import com.anycl.customer.service.AdminUserService;
import com.anycl.customer.service.CustomerService;
import com.anycl.customer.vo.CustomerVo;
import com.anycl.customer.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.http.HttpSession;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@SuppressWarnings("all")
public class CustomerServiceImpl implements CustomerService {

    private AdminUserService adminUserService = new AdminUserServiceImpl();

    private CustomerRepository customerRepository = new CustomerRepositoryImpl();

    @Override
    public CustomerVo addCustomer(CustomerVo customerVo, HttpSession session) throws CustomerException {
        if (!checkLogin(session))
            throw new CustomerException(Constants.ErrorMsg.USER_LOGIN_ERROR);
        if (!customerVo.createValidate()) {
            throw new CustomerException(Constants.ErrorMsg.REQUEST_PARAM_ERROR);
        }
        Customer customer = new Customer();
        try {
            BeanUtils.copyProperties(customer, customerVo);
        } catch (Exception e) {
            log.info(Constants.ErrorMsg.BEAN_UTILS_ERROR);
            throw new CustomerException(Constants.ErrorMsg.INNER_ERROR);
        }
        customer.setStatus(Constants.OK_STATUS);
        customer.setCreateTime(new Timestamp(System.currentTimeMillis()));
        customer.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        int key = customerRepository.insertCustomer(customer);
        if (key < 1)
            throw new CustomerException(Constants.ErrorMsg.UPDATE_ERROR);
        customer.setId(Long.valueOf(key));
        CustomerVo returnVo = new CustomerVo();
        try {
            BeanUtils.copyProperties(returnVo, customer);
        } catch (Exception e) {
            log.info(Constants.ErrorMsg.BEAN_UTILS_ERROR);
            throw new CustomerException(Constants.ErrorMsg.INNER_ERROR);
        }
        log.info(returnVo.toString());
        return returnVo;
    }

    @Override
    public CustomerVo deleteCustomerById(Long id, HttpSession session) throws CustomerException {
        if (!checkLogin(session))
            throw new CustomerException(Constants.ErrorMsg.USER_LOGIN_ERROR);
        if (null == id)
            throw new CustomerException(Constants.ErrorMsg.REQUEST_PARAM_ERROR);
        Customer customer = customerRepository.selectCustomerById(id);
        if (customer == null)
            throw new CustomerException(Constants.ErrorMsg.CAN_NOT_FOUND_RECORD);
        customer.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        int num = customerRepository.deleteCustomerById(id);
        if (num < 1)
            throw new CustomerException(Constants.ErrorMsg.UPDATE_ERROR);
        return CustomerVo.builder().id(customer.getId())
                .name(customer.getName()).build();
    }

    @Override
    public CustomerVo updateCustomer(CustomerVo customerVo, HttpSession session) throws CustomerException{
        if (!checkLogin(session))
            throw new CustomerException(Constants.ErrorMsg.USER_LOGIN_ERROR);
        if (!customerVo.updateValidate())
            throw new CustomerException(Constants.ErrorMsg.REQUEST_PARAM_ERROR);
        Customer customer = customerRepository.selectCustomerById(customerVo.getId());
        if (customer == null)
            throw new CustomerException(Constants.ErrorMsg.CAN_NOT_FOUND_RECORD);
        try {
            BeanUtils.copyProperties(customer, customerVo);
        } catch (Exception e) {
            log.info(Constants.ErrorMsg.BEAN_UTILS_ERROR);
            throw new CustomerException(Constants.ErrorMsg.INNER_ERROR);
        }
        customer.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        log.info(customer.toString());
        int num = customerRepository.updateCustomer(customer);
        if (num < 1)
            throw new CustomerException(Constants.ErrorMsg.UPDATE_ERROR);
        Customer dbCustomer = customerRepository.selectCustomerById(customerVo.getId());
        CustomerVo returnVo = new CustomerVo();
        try {
            BeanUtils.copyProperties(returnVo, dbCustomer);
        } catch (Exception e) {
            log.info(Constants.ErrorMsg.BEAN_UTILS_ERROR);
            throw new CustomerException(Constants.ErrorMsg.INNER_ERROR);
        }
        return returnVo;
    }

    @Override
    public CustomerVo selectCustomerById(Long id, HttpSession session) throws CustomerException {
        if (!checkLogin(session))
            throw new CustomerException(Constants.ErrorMsg.USER_LOGIN_ERROR);
        if (null == id)
            throw new CustomerException(Constants.ErrorMsg.REQUEST_PARAM_ERROR);
        Customer customer = customerRepository.selectCustomerById(id);
        CustomerVo customerVo = new CustomerVo();
        try {
            BeanUtils.copyProperties(customerVo, customer);
        } catch (Exception e) {
            log.info(Constants.ErrorMsg.BEAN_UTILS_ERROR);
        }
        return customerVo;
    }

    @Override
    public List<CustomerVo> selectAllCustomer(HttpSession session) throws CustomerException {
        if (!checkLogin(session))
            throw new CustomerException(Constants.ErrorMsg.USER_LOGIN_ERROR);
        List<Customer> customerList = customerRepository.selectAllCustomer();
        List<CustomerVo> customerVos = new ArrayList<>();
        for(Customer customer: customerList) {
            CustomerVo customerVo = new CustomerVo();
            try {
                BeanUtils.copyProperties(customerVo, customer);
            } catch (Exception e) {
                log.info(Constants.ErrorMsg.BEAN_UTILS_ERROR);
                throw new CustomerException(Constants.ErrorMsg.INNER_ERROR);
            }
            customerVos.add(customerVo);
        }
        return customerVos;
    }

    private boolean checkLogin(HttpSession session) {
        UserVo user = adminUserService.checkLogin(session);
        boolean result = false;
        if (user != null)
            result = true;
        return result;
    }
}
